package com.ruoyi.framework.multiTenant;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.util.Arrays;
import java.util.List;

@Component
@Intercepts({
    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class TenantSqlInterceptor implements Interceptor {

    private static final String ADMIN_USERNAME = "admin";
    private static final List<String> IGNORE_TABLES = Arrays.asList(
        "sys_config", "sys_dict_data", "sys_dict_type", "sys_menu",
        "sys_job", "sys_notice", "sys_role", "sys_role_menu",
        "sys_user_role", "sys_dept", "ds_college");


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("拦截器执行开始 ==================");

        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");

        System.out.println("拦截SQL: " + mappedStatement.getId());

        // 不处理非SELECT语句
        if (mappedStatement.getSqlCommandType() != SqlCommandType.SELECT) {
            System.out.println("非SELECT语句，不处理");
            return invocation.proceed();
        }

        // 获取原始SQL
        BoundSql boundSql = statementHandler.getBoundSql();
        String originalSql = boundSql.getSql();
        System.out.println("原始SQL: " + originalSql);

        // 超级管理员不限制
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser != null) {
            System.out.println("当前用户: " + loginUser.getUsername());
        }

        if (loginUser != null && ADMIN_USERNAME.equals(loginUser.getUsername())) {
            System.out.println("管理员用户不添加租户条件");
            return invocation.proceed();
        }

        // 获取当前用户学院ID
        Integer collegeId = CollegeTenantContext.getCollegeId();
        System.out.println("当前租户ID: " + collegeId);

        if (collegeId == null) {
            System.out.println("租户ID为空，不添加条件");
            return invocation.proceed();
        }

        // 判断SQL是否需要添加租户条件
        String tableName = getMainTableName(originalSql);
        System.out.println("解析的表名: " + tableName);

        if (IGNORE_TABLES.contains(tableName)) {
            System.out.println("忽略的表，不添加条件");
            return invocation.proceed();
        }

        // 修改SQL添加学院条件
        String tenantSql = addTenantCondition(originalSql, collegeId);
        System.out.println("修改后SQL: " + tenantSql);

        metaObject.setValue("delegate.boundSql.sql", tenantSql);

        return invocation.proceed();
    }


    // 添加租户条件
    private String addTenantCondition(String sql, Integer collegeId) {
        // 此处实现SQL解析和条件添加逻辑
        // 可使用JSqlParser等工具实现更精确的SQL解析和修改

        // 简单示例
        if (sql.toLowerCase().contains(" where ")) {
            return sql + " AND college_id = " + collegeId;
        } else {
            return sql + " WHERE college_id = " + collegeId;
        }
    }

    // 获取主表名
    // 获取主表名 - 增强版
    private String getMainTableName(String sql) {
        String lowerSql = sql.toLowerCase();

        // 处理带别名的情况
        int fromIndex = lowerSql.indexOf(" from ");
        if (fromIndex < 0) {
            return "";
        }

        String afterFrom = lowerSql.substring(fromIndex + 6).trim();

        // 处理多种分隔符
        int spaceIndex = afterFrom.indexOf(" ");
        int whereIndex = afterFrom.indexOf(" where ");
        int joinIndex = afterFrom.indexOf(" join ");
        int leftJoinIndex = afterFrom.indexOf(" left join ");
        int rightJoinIndex = afterFrom.indexOf(" right join ");
        int groupByIndex = afterFrom.indexOf(" group by ");
        int orderByIndex = afterFrom.indexOf(" order by ");

        // 找出最近的分隔符
        int endIndex = Integer.MAX_VALUE;
        if (spaceIndex > 0) endIndex = Math.min(endIndex, spaceIndex);
        if (whereIndex > 0) endIndex = Math.min(endIndex, whereIndex);
        if (joinIndex > 0) endIndex = Math.min(endIndex, joinIndex);
        if (leftJoinIndex > 0) endIndex = Math.min(endIndex, leftJoinIndex);
        if (rightJoinIndex > 0) endIndex = Math.min(endIndex, rightJoinIndex);
        if (groupByIndex > 0) endIndex = Math.min(endIndex, groupByIndex);
        if (orderByIndex > 0) endIndex = Math.min(endIndex, orderByIndex);

        if (endIndex == Integer.MAX_VALUE) {
            return afterFrom;
        }

        // 处理表名中可能的别名
        String tableWithAlias = afterFrom.substring(0, endIndex).trim();
        int asIndex = tableWithAlias.toLowerCase().indexOf(" as ");
        if (asIndex > 0) {
            return tableWithAlias.substring(0, asIndex).trim();
        }

        return tableWithAlias;
    }

}
